//******************************************************************************************************
// Copyright 2008 Amazon Technologies, Inc.  
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in 
// compliance with the License. 
//
// You may obtain a copy of the License at:http://aws.amazon.com/apache2.0  This file is distributed on 
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
//
// See the License for the specific language governing permissions and limitations under the License. 
//******************************************************************************************************using System;
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Threading;

//
// References for SQS operations...
//
using Amazon.SQS;
using Amazon.SQS.Mock;
using Amazon.SQS.Model;
using SQS_Client;

namespace SQS
{
	[DefaultEvent("responseEvent")]
    
    /// <summary>
	/// Summary description for SQSControl.
	/// </summary>
    public class Requestor : SQSManager
    {
        string _responseQueue = null;
        
        #region Events
        /// <summary>
		/// A delegate that allows subscribing methods to process message.
		/// </summary>
		public delegate bool ProcessEvent(Requestor requestor, SQSMessage message);
		/// <summary>
		/// </summary>
		/// <remarks>
		/// </remarks>
		[	Bindable( true ), Category( "Events" ), 
		Description( "Event to process incoming responses" )]
		public event ProcessEvent responseEvent = null;
		/// <summary>
		/// </summary>
        #endregion Events
        #region Properties
		/// <summary>
		/// </summary>
        [Bindable( false ), Browsable( false ),
        DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
		public string ResponseQueue
		{
			get { return _responseQueue; }
		}
        #endregion Properties
    
        public string MakeRequest(string request)
        {
            SQSMessage  r;
            string      messageId;
            
            //
            // Make sure the object is running...
            //
            if (this.Running == false) Start();
            
            //
            // Enqueue message
            //
            r          = new SQSMessage(_responseQueue, request);
            messageId = Client.SendMessage(Queue, r.Serialize());
        
            return messageId;
        }
    
        protected override string ResolvePollQueue()
        {
            //    
            // Construct response queue name...
            //
            this._responseQueue = Queue + "-rsp-" + System.Environment.MachineName;
            
            if (_responseQueue.Length > 100)
                _responseQueue = _responseQueue.Substring(0, 100);
        
            Client.CreateQueue(_responseQueue);
            return _responseQueue;
        }
    
        protected override bool MessageReceived(Amazon.SQS.Model.Message msg)
        {
            SQSMessage  response = new SQSMessage(msg);
            bool        result   = false;
            
            //
            // Does the event live in a GUI object?
            //
            if (responseEvent.Target is System.Windows.Forms.Form)
            {
                object[]                    p;
                System.Windows.Forms.Form   parent;
                
                //
                // GUI objects need to be called differently - as they are single threaded
                //
                parent = (System.Windows.Forms.Form)responseEvent.Target;
            
                //
                // Allocate an object array for parameters and Invoke the event method
                //
                p       = new object[2];
                p[0]    = this;
                p[1]    = response;
                result  = (bool)parent.Invoke(responseEvent, p);
            }
            else 
            {
                //
                // Otherwise - we assume the method is thread safe...
                //
                result = responseEvent(this, response);
            }
            
            return result;
        }
    }
}
